package com.example.substation.common;

import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

/**
 * REST统一异常处理
 */
@RestControllerAdvice
public class ExceptionHandlerAdvice {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandlerAdvice.class);

    // ---------------------Frame-----------------------------
    @ExceptionHandler(FrameException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handlerFrameException(FrameException e) {
        LOGGER.debug("自定义异常:", e);
        return FrameResponse.failure(e.getCode(), e.getMessage());
    }

    // ----------------------Data binding------------------------------
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handleErrorParameterException(BindException ex) {
        LOGGER.debug("参数错误:" + ex.getMessage());
        return FrameResponse.failure("参数错误");
    }

    // -----------------------Request------------------------------------------------
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public FrameResponse handleMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        LOGGER.debug("错误的请求方式:" + e.getMessage());
        return FrameResponse.failure("错误的请求方式");
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handleMissingParameterException(MissingServletRequestParameterException e) {
        LOGGER.debug("参数缺失:" + e.getMessage());
        return FrameResponse.failure("参数缺失");
    }

    // ----------------------------data--------------------------------------
    @ExceptionHandler(DataAccessException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handlerDataAccessException(DataAccessException e) {
        LOGGER.error("数据库异常:", e);
        return FrameResponse.failure(31000, "数据库异常", null);
    }

    @ExceptionHandler(EmptyResultDataAccessException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handleDataEmptyException(EmptyResultDataAccessException e) {
        LOGGER.info("数据不存在:", e);
        return FrameResponse.failure("数据不存在");
    }

    @ExceptionHandler(DuplicateKeyException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handleDataDualException(DuplicateKeyException e) {
        LOGGER.info("数据重复插入:" + e.getMessage());
        return FrameResponse.failure("数据重复插入");
    }

    @ExceptionHandler(MultipartException.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handlerMultipartException(Throwable ex) {
        String message = "文件上传错误";
        MultipartException mEx = (MultipartException) ex;
        if (ex.getCause() != null) {
            Throwable cause = ex.getCause().getCause();
            if (cause instanceof SizeLimitExceededException) {
                SizeLimitExceededException flEx = (SizeLimitExceededException) cause;
                float permittedSize = flEx.getPermittedSize() / 1024 / 1024;
                message = "文件大小超过" + permittedSize + "MB";
            } else if (cause instanceof FileSizeLimitExceededException) {
                FileSizeLimitExceededException flEx = (FileSizeLimitExceededException) mEx.getCause().getCause();
                float permittedSize = flEx.getPermittedSize() / 1024 / 1024;
                message = "文件大小超过" + permittedSize + "MB";
            }
        }
        LOGGER.debug(message, ex);
        return FrameResponse.failure(message);
    }

    @ExceptionHandler({IllegalStateException.class, IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handlerAssertException(Throwable ex) {
        String errorMessage = ex.getMessage();
        LOGGER.error(errorMessage, ex);
        FrameResponse failure = FrameResponse.failure(30001, errorMessage);
        failure.put("status", false);
        return failure;
    }


    // ---------All--------------------------------
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public FrameResponse handlerException(Exception e) {
        LOGGER.error("系统异常", e);
        return FrameResponse.failure(30000, "系统异常", null);
    }

}
